home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 226-250 / disk_237 / cliprint / cliprint.asm < prev    next >
Assembly Source File  |  1992-05-06  |  6KB  |  175 lines

  1. ;**************************************************************************
  2. ; CLIprint.asm   by Jeff Glatt
  3. ;
  4. ; Some people just starting out in assembly always ask about printing to the
  5. ; CLI. This program demonstrates how to do that.
  6. ;
  7. ; An example of printing to the CLI. Must be linked with a startup code that
  8. ; sets up a variable, _stdout. This variable is the result of a call to
  9. ; dos lib's Output() function, and is the fileHandle of the CLI window from
  10. ; where this program was started. If this program was started from WorkBench
  11. ; then _stdout will be 0. The provided startup code called StartUp.o has
  12. ; been provided for linking with this example. Using BLink,
  13. ;
  14. ; Blink  StartUp.o CLIprint.o small.lib TO CLIPrint
  15. ;
  16. ; This program does the following:
  17. ; 1). Does a straight print of a string using dos lib's Write().
  18. ; 2). Does a print of a NULL-terminated string using an included function
  19. ;     printf. The printf function has the facility to do more than just
  20. ;     print a string. By including format specifiers in the string, a "new"
  21. ;     string is created with additional information in it. A format specifier
  22. ;     is a % character followed immediately by one of the following letters:
  23. ;     lc  - for a character (pass the character on the stack)
  24. ;     ls  - for a string    (pass the string's starting address on the stack)
  25. ;     ld  - for a signed decimal representation (pass the 32 bit value on the stack)
  26. ;     lx  - for a hex representation (pass 32 bit value on stack)
  27. ; See page B-17 of the Exec ROM Kernal manual for additional options.
  28. ; For example, let's say that we have the string
  29. ;
  30. ;Message dc.b 'The number = %ld',0
  31. ;
  32. ; printf would not output the '%ld' part of the string to the CLI. Instead,
  33. ; it would create a new string where the '%ld' would be replaced by a number
  34. ; that you passed on the stack. This number would be represented as an ascii
  35. ; string. So, using the above string, we called printf like so:
  36.  
  37. ;  lea    Message,a0   ;the specifier string goes in a0
  38. ;  moveq  #50,d0       ;let's pass the number 50 as a 32 bit value to printf
  39. ;  move.l d0,-(sp)
  40. ;  bsr    printf
  41. ;  addq.l #4,sp        ;re-adjust for pushing the 50
  42.  
  43. ; Now printf would print this to the CLI
  44. ;
  45. ;The number = 50
  46.  
  47. ; 3). Demonstrates calls to printf with imbedded specifiers.
  48.  
  49.   ;from StartUp.o
  50.   XREF  _stdout,_DOSBase,_SysBase
  51.  
  52.   ;from small.lib
  53.   XREF  _LVOWrite,_LVORawDoFmt
  54.  
  55.   SECTION  printfdata,DATA
  56.  
  57. Message1Len  equ  32  ;don't count terminating NULL
  58. Message1     dc.b 'This is a print using Write().',13,10,0
  59.  
  60. Message2     dc.b 'This is a print using printf().',13,10,0
  61.  
  62. Format1      dc.b 'The number passed to printf = %ld',13,10,0
  63.  
  64. Format2      dc.b 'The string passed to printf is "%ls".',13,10,0
  65. StringInside dc.b 'Hello',0
  66.  
  67. Format3      dc.b 'The number is %ld, and string = %ls',13,10,0
  68.  
  69. Format4      dc.b 'The number in hex = $%lx',13,10,0
  70.  
  71. FinalMsg     dc.b 'Understand, Bozo?',13,10,0
  72.  
  73.   SECTION printfcode,CODE
  74.  
  75.   XDEF _main   ;the first routine you want executed must be called _main.
  76. _main:
  77. ;---Output a straight string via Write()
  78.    lea      Message1,a0
  79.    move.l   a0,d2
  80.    moveq    #Message1Len,d3
  81.    move.l   _stdout,d1
  82.    movea.l  _DOSBase,a6
  83.    jsr      _LVOWrite(a6)
  84. ;---Output a straight string via printf
  85.    lea      Message2,a0
  86.    bsr      printf
  87. ;---Output a number inside of the string specifier via printf
  88.    lea      Format1,a0
  89.    moveq    #50,d0
  90.    move.l   d0,-(sp)
  91.    bsr      printf
  92.    addq.l   #4,sp
  93. ;---Output that number again (but use the hex specifier)
  94.    lea      Format4,a0
  95.    moveq    #50,d0
  96.    move.l   d0,-(sp)
  97.    bsr      printf
  98.    addq.l   #4,sp
  99. ;---Output a string inside of the string specifier via printf
  100.    lea      StringInside,a1
  101.    move.l   a1,-(sp)
  102.    lea      Format2,a0
  103.    bsr      printf
  104.    addq.l   #4,sp
  105. ;---Output a string and number inside of the string specifier
  106. ;  The order to push the args is reverse to the order that they are inserted
  107. ;  into the string (i.e. my %ld came before my %s, so I push StringInside
  108. ;  first then the number 50)
  109.    lea      StringInside,a1
  110.    move.l   a1,-(sp)
  111.    moveq    #50,d0
  112.    move.l   d0,-(sp)
  113.    lea      Format3,a0
  114.    bsr      printf
  115.    addq.l   #8,sp      ;note: re-adjust for 2 LONG pushes
  116. ;---One last insult
  117.    lea      FinalMsg,a0
  118.    bsr      printf
  119. ;---Get out of this program
  120.    rts
  121.  
  122. ;=======================================================================
  123. ; Pass string specifier in a0, and any args on the stack.
  124.  
  125.   XDEF  printf
  126. printf:
  127.    ;---If we're from WorkBench, _stdout = 0. Get out of here.
  128.       move.l   _stdout,d0
  129.       beq.s    noPF
  130.    ;---Get the address of where we pushed any args in a1
  131.       lea      4(sp),a1
  132.    ;---Save some regs
  133.       movem.l  d2/d3/a2/a3/a4/a6,-(sp)
  134.    ;---Save the address of stdout
  135.       movea.l  d0,a4
  136.    ;---Get a buffer on the stack to create a "new" string
  137.    ;   Now we call Exec's RawDoFmt. It does all the work of formatting
  138.    ;   the new string. It needs the address of a function we create. This
  139.    ;   function just throws a char into our "new" buffer. Exec calls this
  140.    ;   for every "new" character it creates.
  141.       moveq    #126,d0
  142.       suba.l   d0,sp
  143.       lea      StoreChar,a2
  144.       movea.l  sp,a3
  145.       ;address of args in a1
  146.       movea.l  _SysBase,a6
  147.       jsr      _LVORawDoFmt(a6)
  148.    ;---Count how many chars are in the string (it will be NULL-terminated)
  149.       moveq    #126-1,d1
  150.       move.l   a3,d2       ;the start of our "new" string
  151. cntC  move.b   (a3)+,d0
  152.       Dbeq     d1,cntC(pc)
  153.    ;---Determine # of chars
  154.       subq.l   #1,a3
  155.       move.l   a3,d3
  156.       sub.l    d2,d3
  157.       beq.s    char0       ;if 0 chars, don't print anything
  158.    ;---Print out to _stdout (which will be the CLI window unless the user
  159.    ;   redirected output on the command line using the '>')
  160.       move.l   a4,d1
  161.       ;address of string in d2
  162.       movea.l  _DOSBase,a6
  163.       jsr      _LVOWrite(a6)
  164.    ;---Get rid of our "new" buffer
  165. char0 moveq    #126,d0
  166.       adda.l   d0,sp
  167.    ;---Restore regs
  168.       movem.l  (sp)+,d2/d3/a2/a3/a4/a6
  169. noPF  rts
  170.  
  171. ;Exec passes a "new" character (in d0) to be stored in our "new" buffer
  172. ;(address in a3).
  173. StoreChar move.b   d0,(a3)+
  174.           rts
  175.